﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using Icoders.MarketTracker.Core.MasterData;
using Icoders.MarketTracker.Core.Repository.MasterDataRepositories;
using Icoders.MarketTracker.Core.Validation;
using Icoders.MarketTracker.Data.EF;
using Icoders.MarketTracker.Data.Utils;
using Icoders.MarketTracker.Data.Utils.Caching;

namespace Icoders.MarketTracker.Data.Repository.MasterDataRepositories
{
    public class ZoneRepository :RepositoryBase, IZoneRepository
    {
         private AppDataContext _ctx;
         private ICacheProvider _cacheProvider;

        public ZoneRepository(AppDataContext ctx, ICacheProvider cacheProvider)
        {
            _ctx = ctx;
            _cacheProvider = cacheProvider;
        }

        public int Save(Zone entity)
       {
           ValidationResultInfo vri = Validate(entity);
           if(!vri.IsValid)
           {
               throw new DomainValidationException(vri, "Zone Details provided not Valid");
           }
           DateTime date = TimeUtil.GetDateTime();
           TblZone tbl= _ctx.TblZone.FirstOrDefault(s => s.Id == entity.Id);
           if (tbl == null)
           {
               tbl = new TblZone();
               tbl.CreatedOn = date;
               tbl.StatusId = (int) MasterEntityStatus.New;
               _ctx.TblZone.AddObject(tbl);
               tbl.Description = entity.Description;
               tbl.Code = entity.Code;
           }
           tbl.UpdatedOn = date;
           tbl.Name = entity.Name;
           tbl.AreaId = entity.AreaId;
           _ctx.SaveChanges();
           _cacheProvider.Put(_cacheListKey, _ctx.TblZone.Where(x => x.StatusId != 3).Select(s => s.Id).ToList());
           _cacheProvider.Remove(string.Format(_cacheKey, tbl.Id));
           return tbl.Id;
       }

       public Zone GetById(int id)
       {
           Zone entity = (Zone)_cacheProvider.Get(string.Format(_cacheKey, id));
           if (entity == null)
           {
               var tbl = _ctx.TblZone.FirstOrDefault(s => s.Id == id);
               if (tbl != null)
               {
                   entity = Map(tbl);
                   _cacheProvider.Put(string.Format(_cacheKey, entity.Id), entity);
               }

           }
           return entity;
       }
        public Zone GetbyName(int id)
        {
            var tbl = _ctx.TblZone.FirstOrDefault(s => s.Id == id);
            if (tbl == null) return null;
            return Map(tbl);
        }

        public List<Zone> GetAll()
       {
          // return _ctx.TblZone.ToList().Where(p => p.StatusId != (int)MasterEntityStatus.Deleted).Select(n => Map(n)).ToList();
           IList<Zone> entities = null;
           IList<int> ids = (IList<int>)_cacheProvider.Get(_cacheListKey);
           if (ids != null)
           {
               entities = new List<Zone>(ids.Count);
               foreach (int id in ids)
               {
                   Zone entity = GetById(id);
                   if (entity != null)
                       entities.Add(entity);
               }
           }
           else
           {
               entities = _ctx.TblZone.Where(x => x.StatusId != 3).ToList().Select(s => Map(s)).ToList();
               if (entities != null && entities.Count > 0)
               {
                   ids = entities.Select(s => s.Id).ToList(); //new List<int>(persons.Count);
                   _cacheProvider.Put(_cacheListKey, ids);
                   foreach (Zone p in entities)
                   {
                       _cacheProvider.Put(string.Format(_cacheKey, p.Id), p);
                   }

               }
           }
           return entities.ToList();
       }

        public void Delete(int id)
        {
            var tbl = _ctx.TblUser.FirstOrDefault(s => s.Id == id);
            if (tbl != null)
            {
                tbl.StatusId = (int)MasterEntityStatus.Deleted;
                _ctx.SaveChanges();
                _cacheProvider.Put(_cacheListKey, _ctx.TblZone.Where(x => x.StatusId != 3).Select(s => s.Id).ToList());
                _cacheProvider.Remove(string.Format(_cacheKey, tbl.Id));
            }
        }

        private Zone Map(TblZone tblZone)
       {
           return new Zone() //(tblCountry.Id)
           {
               Id = tblZone.Id,
               Code = tblZone.Code,
               Name = tblZone.Name,
               AreaId = tblZone.TblArea.Id,
               AreaName = tblZone.TblArea.Name,
               Description = tblZone.Description,
               UpdatedOn = tblZone.UpdatedOn,
               CreatedOn = tblZone.CreatedOn,
               Status = (MasterEntityStatus)tblZone.StatusId

           };
       }

       public ValidationResultInfo Validate(Zone objToValidate)
       {
           ValidationResultInfo vri = objToValidate.BasicValidation();
           bool hasDuplicateName = GetAll().Where(p => p.AreaId == objToValidate.AreaId & p.Name == objToValidate.Name).Any();
           if (hasDuplicateName)
           {
               vri.Results.Add(new ValidationResult("Duplicate Zone Found"));
           }
           return vri;
       }

        protected override string _cacheKey
        {
            get { return "Zone-{0}"; }
        }

        protected override string _cacheListKey
        {
            get { return "ZoneList"; }
        }
    }
}
